﻿#include "process_info.h"



#ifdef _WIN32
#include <Windows.h>
#include <TlHelp32.h>
#include <Psapi.h>
#pragma comment(lib, "Psapi.lib")
#else
#include <fstream>
#include <sstream>
#endif

void as::tools::ProcessInfo::GetProcessInfo(uint32_t processId, std::string &processName, std::string &processPath)
{
#ifdef _WIN32
	HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processId);
	if (hProcess == NULL) {
		return;
	}

	// 获取进程路径
	TCHAR szPath[MAX_PATH];
	if (GetModuleFileNameEx(hProcess, NULL, szPath, MAX_PATH) == 0) {
		CloseHandle(hProcess);
		return;
	}
	processPath = szPath;

	// 获取进程名
	TCHAR szName[MAX_PATH];
	DWORD dwSize = sizeof(szName) / sizeof(*szName);
	if (!QueryFullProcessImageName(hProcess, 0, szName, &dwSize)) {
		CloseHandle(hProcess);
		return;
	}
	processName = szName;
	CloseHandle(hProcess);
#else
	std::ifstream procFile("/proc/" + std::to_string(processId) + "/cmdline");
	if (!procFile.is_open()) {
		std::cerr << "Error opening process file." << std::endl;
		return ;
	}

	// 读取进程命令行参数
	std::stringstream ss;
	ss << procFile.rdbuf();
	std::string cmdline = ss.str();

	// 提取进程名和进程路径
	std::size_t pos = cmdline.find('\0');
	processPath = cmdline.substr(0, pos);
	processName = processPath.substr(processPath.rfind('/') + 1);
#endif
}

std::vector<as::tools::ProcessDetail> as::tools::ProcessInfo::GetProcessInfo(const std::string &processName)
{
	std::vector<as::tools::ProcessDetail> vec;
#ifdef _WIN32
	HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if (hProcessSnap == INVALID_HANDLE_VALUE) {
		return vec;
	}

	PROCESSENTRY32 pe32;
	pe32.dwSize = sizeof(PROCESSENTRY32);

	if (!Process32First(hProcessSnap, &pe32)) {
		CloseHandle(hProcessSnap);
		return vec;
	}

	do {
		if (strcmp(pe32.szExeFile, processName.c_str()) == 0)
		{
			as::tools::ProcessDetail detail;
			detail.pid_ = pe32.th32ProcessID;
			detail.name_ = pe32.szExeFile;
			detail.path_ = GetProcessExePath(detail.pid_);
			vec.emplace_back(detail);
		}
	} while (Process32Next(hProcessSnap, &pe32));
#else
#endif


	return vec;
}

std::string as::tools::ProcessInfo::GetProcessExePath(uint32_t processId)
{
#ifdef _WIN32
	HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processId);
	if (hProcess == NULL) {
		return "";
	}

	TCHAR szPath[MAX_PATH];
	DWORD dwSize = sizeof(szPath) / sizeof(*szPath);
	if (!QueryFullProcessImageName(hProcess, 0, szPath, &dwSize)) {
		CloseHandle(hProcess);
		return "";
	}

	CloseHandle(hProcess);
	return szPath;
#else
	return 0;
#endif
}

